
#include "ManagerResource.h"
#include <iostream>
#include "../Constants.h"

CManagerResource::CManagerResource()
{

}
//----�������� ������--------------------------
bool CManagerResource::GetShablon( const char* FileShablon, vector<SAllShablon> &AllShablonResult )
{
	SAllShablon AllShablonTemp;
	SOneShablon OneShablonTemp;
	char buffer[1024];
	STextTexture TextTexture;
	bool Contain = false;//TODO Flag proverki zapolneniy AllShablonTemp, dly nevneseniy pustogo soderjimogo

	FILE *file = fopen( FileShablon, "rt" );
	while ( fgets( buffer, 1023, file ) )
	{
		buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';

		//----CLabel--------------------------------------
		if ((strcmp(buffer,"CLabel") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_LABEL;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CEdit--------------------------------------
		if ((strcmp(buffer,"CEdit") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_EDIT;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CMemo--------------------------------------
		if ((strcmp(buffer,"CMemo") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_MEMO;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CListBox--------------------------------------
		if ((strcmp(buffer,"CListBox") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_LISTBOX;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CComboBox--------------------------------------
		if ((strcmp(buffer,"CComboBox") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_COMBOBOX;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CButton--------------------------------------
		if ((strcmp(buffer,"CButton") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_BUTTON;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CCheckBox--------------------------------------
		if ((strcmp(buffer,"CCheckBox") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_CHECKBOX;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CRadioButton--------------------------------------
		if ((strcmp(buffer,"CRadioButton") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_RADIOBUTTON;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CProgressBar--------------------------------------
		if ((strcmp(buffer,"CProgressBar") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_PROGRESSBAR;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CTrackBar--------------------------------------
		if ((strcmp(buffer,"CTrackBar") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_TRACKBAR;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CPanel--------------------------------------
		if ((strcmp(buffer,"CPanel") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_PANEL;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CInventar--------------------------------------
		if ((strcmp(buffer,"CInventar") == 0))
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			Contain = true;
			AllShablonTemp.Tip = TYPE_INVENTAR;
			AllShablonTemp.OneShablon.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		if(strcmp(buffer,"end") == 0)
		{
			if (Contain != false)
				AllShablonResult.push_back(AllShablonTemp);
			break;
		}
		//TODO Sdelat proverku sscanf na poluchenie nujnoi informatii, otsekay musor
		sscanf( buffer, "%s %s %s %s %s", TextTexture.Texture1,
				TextTexture.Texture2, TextTexture.Texture3,
				TextTexture.Texture4, TextTexture.Texture5);
		UINT x, y;
		OneShablonTemp.Texture1 = SetUpTexture2D( std::string(TextTexture.Texture1), x, y );
		OneShablonTemp.Texture2 = SetUpTexture2D( std::string(TextTexture.Texture2), x, y );
		OneShablonTemp.Texture3 = SetUpTexture2D( std::string(TextTexture.Texture3), x, y );
		OneShablonTemp.Texture4 = SetUpTexture2D( std::string(TextTexture.Texture4), x, y );
		OneShablonTemp.Texture5 = SetUpTexture2D( std::string(TextTexture.Texture5), x, y );
		OneShablonTemp.Size.x = float(x)/float(WINDOW_WIDTH);
		OneShablonTemp.Size.y = float(y)/float(WINDOW_HEIGHT);
		AllShablonTemp.OneShablon.push_back(OneShablonTemp);
	}
	fclose(file);
	file = NULL;

	return true;
}

bool CManagerResource::GetMapGUI( const char* FileControl, vector<SMapGUI> &MapGUIResult )
{
	SMapGUI MapGUITemp;
	SOneMapGUI OneMapGUITemp;
	char buffer[1024];
	char NameTemp[1024];
	char ParentTemp[1024];
	bool Contain = false;//TODO Flag proverki zapolneniy MapGUITemp, dly nevneseniy pustogo soderjimogo

	FILE *file = fopen( FileControl, "rt" );
	while ( fgets( buffer, 1023, file ) )
	{
		buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';

		//----CLabel--------------------------------------
		if ((strcmp(buffer,"CLabel") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_LABEL;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CEdit--------------------------------------
		if ((strcmp(buffer,"CEdit") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_EDIT;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CMemo--------------------------------------
		if ((strcmp(buffer,"CMemo") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_MEMO;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CListBox--------------------------------------
		if ((strcmp(buffer,"CListBox") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_LISTBOX;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CComboBox--------------------------------------
		if ((strcmp(buffer,"CComboBox") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_COMBOBOX;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CButton--------------------------------------
		if ((strcmp(buffer,"CButton") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_BUTTON;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CCheckBox--------------------------------------
		if ((strcmp(buffer,"CCheckBox") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_CHECKBOX;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CRadioButton--------------------------------------
		if ((strcmp(buffer,"CRadioButton") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_RADIOBUTTON;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CProgressBar--------------------------------------
		if ((strcmp(buffer,"CProgressBar") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_PROGRESSBAR;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CTrackBar--------------------------------------
		if ((strcmp(buffer,"CTrackBar") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_TRACKBAR;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CPanel--------------------------------------
		if ((strcmp(buffer,"CPanel") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_PANEL;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		//----CInventar--------------------------------------
		if ((strcmp(buffer,"CInventar") == 0))
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			Contain = true;
			MapGUITemp.Tip = TYPE_INVENTAR;
			MapGUITemp.OneMapGUI.clear();
			fgets( buffer, 1023, file );
			buffer[strlen(buffer) - OFFSET_FROM_LINE_END] = '\0';
		}
		if(strcmp(buffer,"end") == 0)
		{
			if (Contain != false)
				MapGUIResult.push_back(MapGUITemp);
			break;
		}
		//TODO Sdelat proverku sscanf na poluchenie nujnoi informatii, otsekay musor
		sscanf( buffer, "%s %s %d %f %f", NameTemp,
				ParentTemp, &OneMapGUITemp.TipShablon,
				&OneMapGUITemp.Position.x, &OneMapGUITemp.Position.y);
		OneMapGUITemp.Name = NameTemp;
		OneMapGUITemp.Parent = ParentTemp;
		if ( OneMapGUITemp.Parent == "NULL" )
			OneMapGUITemp.Parent = "";

		MapGUITemp.OneMapGUI.push_back(OneMapGUITemp);
	}
	fclose(file);
	file = NULL;

	return true;
}

/**
 *
 * Function loads texture with name FileName and returns it's dimensions through and Height
 *
 * The function has problems with .dds files with mip-levels,
 * in this case use overloaded version SetUpTexture2D( const std::string FileName )
 */
GLuint
CManagerResource::SetUpTexture2D( const std::string FileName, UINT &Width, UINT &Height )
{
	GLuint Result = 0;
	if ( !FileName.empty() )
	{
		gli::texture2D Texture = gli::gtx::loader::load( FileName );
		if( !Texture.empty() )
		{
			gli::gtx::gl_texture2d::detail::texture_desc TextureDesc =
					gli::gtx::gl_texture2d::detail::gli2ogl_cast( Texture.format() );

			GLint Alignment = 0;
			glGetIntegerv(GL_UNPACK_ALIGNMENT, &Alignment);

			glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

			GLuint Name = 0;
			glGenTextures(1, &Name);
			glBindTexture(GL_TEXTURE_2D, Name);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Texture.levels() > 1 ? GL_NEAREST_MIPMAP_NEAREST : GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

			Width = GLsizei( Texture[0].dimensions().x );
			Height = GLsizei( Texture[0].dimensions().y );


			if( gli::size( Texture, gli::BIT_PER_PIXEL ) ==  ( gli::size( Texture, gli::BLOCK_SIZE ) << 3 ))
			{
				for(gli::texture2D::level_type Level = 0; Level < Texture.levels(); ++Level)
				{
					glTexImage2D( GL_TEXTURE_2D,
								  GLint(Level),
							      TextureDesc.InternalFormat,
							      Width,
							      Height,
							      0,
							      TextureDesc.ExternalFormatRev,
							      TextureDesc.Type,
							      Texture[Level].data() );
				}
			}
			else
			{
				for( gli::texture2D::level_type Level = 0; Level < Texture.levels(); ++Level )
				{
					glCompressedTexImage2D( GL_TEXTURE_2D,
							                GLint(Level),
											TextureDesc.InternalFormat,
											Width,
											Height,
											0,
											GLsizei(Texture[Level].capacity()),
											Texture[Level].data() );
				}
			}

			glBindTexture( GL_TEXTURE_2D, 0 );
			glPixelStorei( GL_UNPACK_ALIGNMENT, Alignment );
		}
		Result = gli::createTexture2D( FileName );
	}
	return Result;
}

GLuint
CManagerResource::SetUpTexture2D( const std::string FileName )
{
	return gli::createTexture2D( FileName );
}

/*
 * The function loads an array of textures is used for multitexturing in GLSL
 */
GLuint
CManagerResource::SetUpTexture2D( const std::vector<std::string> FileNames )
{
	GLuint         Result = 0;
	bool           FirstTexture = true;
	gli::gtx::gl_texture2d::detail::texture_desc TextureDesc;
	GLint          Alignment = 0;
	UINT           ImageWidth, ImageHeight;
	BYTE          *CommonPixelsArray = NULL;
	int            BitPerPixel, BlockSize;
	UINT           Texture3DLevelsCounter = 0;
	GLenum         OneImageArraySize = 0;

	if ( !FileNames.empty() )
	{

		for ( std::vector<std::string>::const_iterator it = FileNames.begin(), end = FileNames.end();
			  it != end; ++it )
		{
			std::string FileName = *it.base();
			gli::texture2D Texture = gli::gtx::loader::load( FileName );
			if( Texture.empty() )
			{
				fprintf( stderr, "Error texture %s not found...", FileName.c_str() );
				break;
			}

			gli::gtx::gl_texture2d::detail::texture_desc CurrentDescriptor =
					gli::gtx::gl_texture2d::detail::gli2ogl_cast( Texture.format() );
			if ( FirstTexture )
			{
				TextureDesc = CurrentDescriptor;

				ImageWidth = GLsizei( Texture[0].dimensions().x );
				ImageHeight = GLsizei( Texture[0].dimensions().y );
				BitPerPixel = (int)gli::size( Texture, gli::BIT_PER_PIXEL );
				BlockSize = (int)gli::size( Texture, gli::BLOCK_SIZE );
				OneImageArraySize = (BitPerPixel / 8) * ImageWidth * ImageHeight;

				CommonPixelsArray = new BYTE[OneImageArraySize * FileNames.size()];
			}
			else if ( ( GLsizei( Texture[0].dimensions().x ) != ImageWidth ) ||
					  ( GLsizei( Texture[0].dimensions().y ) != ImageHeight ) ||
					  ( TextureDesc.InternalFormat != CurrentDescriptor.InternalFormat ) )
			{
				fprintf( stderr, "Error texture %s has incompatible format or dimension...", FileName.c_str() );
				break;
			}

			memcpy( CommonPixelsArray + OneImageArraySize * Texture3DLevelsCounter, Texture[0].data(), OneImageArraySize );
			Texture3DLevelsCounter++;
		}

		if ( CommonPixelsArray != NULL )
		{
			glGetIntegerv(GL_UNPACK_ALIGNMENT, &Alignment);
			glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

			glGenTextures( 1, &Result );
			glBindTexture( GL_TEXTURE_2D_ARRAY, Result );

			glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_REPEAT); //What to do when texture coordinate is not in [0..1]
			glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_REPEAT);

			if( BitPerPixel == ( BlockSize << 3 ) )
			{
				glTexImage3D( GL_TEXTURE_2D_ARRAY,
							  0, //TODO Add support for loading miplevels
							  TextureDesc.InternalFormat,
							  ImageWidth,
							  ImageHeight,
							  Texture3DLevelsCounter,
							  0,
							  TextureDesc.ExternalFormatRev,
							  TextureDesc.Type,
							  CommonPixelsArray );

			}
			else
			{
				glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY,
							            0, //TODO Add support for loading miplevels
							            TextureDesc.InternalFormatCompressed,
										ImageWidth,
										ImageHeight,
										Texture3DLevelsCounter,
										0,
										OneImageArraySize * Texture3DLevelsCounter,
										CommonPixelsArray );
			}

			glBindTexture( GL_TEXTURE_2D_ARRAY, 0 );
			glPixelStorei( GL_UNPACK_ALIGNMENT, Alignment );
		}

		delete [] CommonPixelsArray;
	}

	return Result;
}


